package cn.yeziji.forum.config.auth;

import cn.yeziji.forum.common.PasswordSecurity;
import cn.yeziji.forum.filter.JwtAuthFilter;
import cn.yeziji.forum.filter.JwtLoginFilter;
import cn.yeziji.forum.filter.TokenRefreshFilter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;

/**
 * security 配置
 *
 * @author gzkemays
 * @since 2021/12/21 16:00
 */
@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Resource private MemberUserDetailServiceImpl memberUserDetailService;

  /**
   * 用户鉴权配置
   *
   * @param auth 权限管理器
   * @throws Exception 鉴权发生异常
   */
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(memberUserDetailService)
        .passwordEncoder(
            new PasswordEncoder() {
              /**
               * 密码加密
               *
               * @param charSequence 原密码
               * @return 加密密码
               */
              @Override
              public String encode(CharSequence charSequence) {
                return DigestUtils.md5DigestAsHex(charSequence.toString().getBytes());
              }

              /**
               * 校验密码
               *
               * @param userPassword 用户输入的密码
               * @param dbPassword 数据库获取的密码 -- password
               * @return 校验结果
               */
              @Override
              public boolean matches(CharSequence userPassword, String dbPassword) {
                return dbPassword.equals(
                    PasswordSecurity.generatedPassword(userPassword.toString()));
              }
            });
  }

  @Override
  public void configure(WebSecurity web) {
    web.ignoring().antMatchers(FilterExUrls.urls());
  }
  /**
   * Http 请求拦截处理配置
   *
   * @param http http security 配置
   * @throws Exception 配置异常
   */
  @Override
  protected void configure(HttpSecurity http) throws Exception {
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
        expressionInterceptUrlRegistry = http.authorizeRequests();
    expressionInterceptUrlRegistry
        .antMatchers("/**")
        .fullyAuthenticated()
        .anyRequest()
        .permitAll()
        .and()
        .csrf()
        .disable()
        .addFilter(new JwtAuthFilter(authenticationManager()))
        .addFilter(new JwtLoginFilter(authenticationManager()))
        .csrf()
        .disable()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }
}
